package com.garen.fire.biz.impl;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import javax.imageio.ImageIO;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.garen.fire.biz.IFireCasePhotoBiz;
import com.garen.fire.dao.IFireCasePhotoDao;
import com.garen.fire.entity.FireCasePhoto;
import com.garen.utils.CommonUtils;

@Service
public class FireCasePhotoBizImpl implements IFireCasePhotoBiz {

	private static final String ORIGINAL_BASE_PATH = CommonUtils.getRealPath("/firecasephoto/original/");
	private static final String PHOTO_BASE_PATH = CommonUtils.getRealPath("/firecasephoto/photo/");
	private static final String PREVIEW_BASE_PATH = CommonUtils.getRealPath("/firecasephoto/preview/");
	private static final int MAX_THUMBNAIL_WIDTH = 360;
	private static final int MAX_THUMBNAIL_HEIGHT = 360;
	
	private static final int MAX_PIXEL = 500 * 10000;
	
	
	@Autowired
	private IFireCasePhotoDao fireCasePhotoDao;

	@Override
	public FireCasePhoto upload(String ajbh, String binaryStream, String fileType) {
		// TODO Auto-generated method stub
		Date date = new Date(); // 当前时间
		SimpleDateFormat sdf = new SimpleDateFormat("HHmmss");
		String randomNum = "" + ((int) (Math.random() * 1000)); // 随机数字
		String fileName = sdf.format(date) + "_" + randomNum + "." + fileType; // 文件名
		String subPath = ajbh + "/"; // 文件子路径
		String originalFullName = ORIGINAL_BASE_PATH +subPath +fileName;
		String originalPath = ORIGINAL_BASE_PATH +subPath;
		String photoPath = PHOTO_BASE_PATH + subPath;
		String previewPath = PREVIEW_BASE_PATH + subPath ;
		
		

		// 构造实体并保存
		FireCasePhoto photo = new FireCasePhoto();
		photo.setFireAjbh(ajbh);
		photo.setPhotoPath(subPath + fileName);
		photo.setUploadTime(date);
		this.fireCasePhotoDao.add(photo);

		byte[] byteArray = hex2byte(binaryStream);
		saveByteArrayToFile(byteArray, originalPath, fileName);
		
		//保存压缩图
		thumbnailImage(originalFullName, photoPath,fileName, MAX_PIXEL, false);

		// 保存缩略图
		thumbnailImage(originalFullName, previewPath,fileName, MAX_THUMBNAIL_WIDTH, MAX_THUMBNAIL_HEIGHT, false);

		return photo;
	}
	
	@Override
	public FireCasePhoto upload(String ajbh, MultipartFile file, String fileType) {
		// TODO Auto-generated method stub
		Date date = new Date(); // 当前时间
		SimpleDateFormat sdf = new SimpleDateFormat("HHmmss");
		String randomNum = "" + ((int) (Math.random() * 1000)); // 随机数字
		String fileName = sdf.format(date) + "_" + randomNum + "." + fileType; // 文件名
		String subPath = ajbh + "/"; // 文件子路径
		String originalFullName = ORIGINAL_BASE_PATH +subPath +fileName;
		String originalPath = ORIGINAL_BASE_PATH +subPath;
		String photoPath = PHOTO_BASE_PATH + subPath;
		String previewPath = PREVIEW_BASE_PATH + subPath ;
		// 构造实体并保存
		FireCasePhoto photo = new FireCasePhoto();
		photo.setFireAjbh(ajbh);
		photo.setPhotoPath(subPath + fileName);
		photo.setUploadTime(date);
		this.fireCasePhotoDao.add(photo);
		
		saveFile(file, originalPath, fileName);

		
		thumbnailImage(originalFullName, photoPath,fileName, MAX_PIXEL, false);
		thumbnailImage(originalFullName, previewPath,fileName, MAX_THUMBNAIL_WIDTH, MAX_THUMBNAIL_HEIGHT, false);

		return photo;
	}

	@Override
	public List<FireCasePhoto> getFireCasePhotoListByAjbh(String ajbh) {
		// TODO Auto-generated method stub

		return this.fireCasePhotoDao.getCasePhotoListByAjbh(ajbh);
	}
	
	
	
	

	@Override
	public String getPhotoPathByPhotoId(int photoId) {
		// TODO Auto-generated method stub
		FireCasePhoto photo = this.fireCasePhotoDao.get(photoId, FireCasePhoto.class);
		return PHOTO_BASE_PATH + photo.getPhotoPath();
	}

	@Override
	public String getPreviewPathByPhotoId(int photoId) {
		// TODO Auto-generated method stub
		FireCasePhoto photo = this.fireCasePhotoDao.get(photoId, FireCasePhoto.class);
		return PREVIEW_BASE_PATH + photo.getPhotoPath();
	}

	/**
	 * <p>
	 * Title: thumbnailImage
	 * </p>
	 * <p>
	 * Description: 根据图片路径生成缩略图
	 * </p>
	 * 
	 * @param sourceFilePath
	 *            原图片路径
	 * @param targetFilePath
	 *            目标图片路径
	 * @param w
	 *            缩略图宽
	 * @param h
	 *            缩略图高
	 * @param force
	 *            是否强制按照宽高生成缩略图(如果为false，则生成最佳比例缩略图)
	 */
	private static void thumbnailImage(String sourceFilePath, String targetFilePath,String targetFileName, int w, int h, boolean force) {

		try {
			File sourceFile = new File(sourceFilePath);
			// ImageIO 支持的图片类型 : [BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG,
			// JPEG, WBMP, GIF, gif]
			String types = Arrays.toString(ImageIO.getReaderFormatNames());
			String suffix = null;
			// 获取图片后缀
			if (sourceFilePath.indexOf(".") > -1) {
				suffix = sourceFilePath.substring(sourceFilePath.lastIndexOf(".") + 1);
			} // 类型和图片后缀全部小写，然后判断后缀是否合法
			if (suffix == null || types.toLowerCase().indexOf(suffix.toLowerCase()) < 0) {
				return;
			}
			Image img = ImageIO.read(sourceFile);
			if (!force) {
				// 根据原图与要求的缩略图比例，找到最合适的缩略图比例
				int width = img.getWidth(null);
				int height = img.getHeight(null);
				if ((width * 1.0) / w < (height * 1.0) / h) {
					if (width > w) {
						h = Integer.parseInt(new java.text.DecimalFormat("0").format(height * w / (width * 1.0)));
					}
				} else {
					if (height > h) {
						w = Integer.parseInt(new java.text.DecimalFormat("0").format(width * h / (height * 1.0)));
					}
				}
			}
			BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
			Graphics g = bi.getGraphics();
			g.drawImage(img, 0, 0, w, h, Color.LIGHT_GRAY, null);
			g.dispose();

			File localFile = new File(targetFilePath);
			if (!localFile.exists()) {
				localFile.mkdirs();
			}
			
			
			// 将图片保存在原目录并加上前缀
			ImageIO.write(bi, suffix, new File(targetFilePath+targetFileName));
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
	
	
	private static void thumbnailImage(String sourceFilePath, String targetFilePath,String targetFileName, int pixel, boolean force) {

		try {
			File sourceFile = new File(sourceFilePath);
			Image img = ImageIO.read(sourceFile);
			
			int sourceWidth = img.getWidth(null);
			int sourceHeight = img.getHeight(null);
			
			int w,h;
			
			if(sourceWidth*sourceHeight<=pixel)
			{
				w=sourceWidth;
				h=sourceHeight;
			}
			else
			{
				double scale = Math.sqrt((pixel * 1.0)/(sourceWidth*sourceHeight));
				w = (int)(sourceWidth*scale);
				h = (int)(sourceHeight*scale);
			}
			thumbnailImage(sourceFilePath,targetFilePath,targetFileName,w,h,force);
			
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}


	}

	private static void saveFile(MultipartFile file, String filePath, String fileName) {
		try {
			File localFile = new File(filePath);
			if (!localFile.exists()) {
				localFile.mkdirs();
			}

			file.transferTo(new File(filePath+fileName));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	
	private static void saveByteArrayToFile(byte[] b, String filePath, String fileName) {
		try {
			File localFile = new File(filePath);
			if (!localFile.exists()) {
				localFile.mkdirs();
			}

			if (b != null) {
				OutputStream os = new FileOutputStream(filePath + fileName);

				os.write(b, 0, b.length);

				os.flush();
				os.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static String byte2hex(byte[] b) // 二进制转字符串
	{
		StringBuffer sb = new StringBuffer();
		String stmp = "";
		for (int n = 0; n < b.length; n++) {
			stmp = Integer.toHexString(b[n] & 0XFF);
			if (stmp.length() == 1) {
				sb.append("0" + stmp);
			} else {
				sb.append(stmp);
			}

		}
		return sb.toString();
	}

	public static byte[] hex2byte(String str) { // 字符串转二进制
		if (str == null)
			return null;
		str = str.trim();
		int len = str.length();
		if (len == 0 || len % 2 == 1)
			return null;
		byte[] b = new byte[len / 2];
		try {
			for (int i = 0; i < str.length(); i += 2) {
				b[i / 2] = (byte) Integer.decode("0X" + str.substring(i, i + 2)).intValue();
			}
			return b;
		} catch (Exception e) {
			return null;
		}
	}

	

}
